//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.UIDesigner
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using Microsoft.Research.ScientificWorkflow.TridentUtilities;

    /// <summary>
    /// Interaction logic for UserDataEntryBaseCtrl.xaml
    /// </summary>
    public partial class UserDataEntryBaseCtrl : UserControl
    {
        /// <summary>
        /// Flag specifying if the value of the input parameter can be null or not.
        /// </summary>
        private bool allowNullAsValue;

        /// <summary>
        /// Fired on click of Ok button.
        /// </summary>
        public event EventHandler<InfoEnteredEventArgs> InfoEntered;

        /// <summary>
        /// Occurs when header drag.
        /// </summary>
        public event EventHandler HeaderDrag;

        /// <summary>
        /// Constructor.
        /// </summary>
        public UserDataEntryBaseCtrl(bool allowNullAsValue)
        {
            InitializeComponent();
            this.brdrHeader.MouseLeftButtonDown += (sender, e) =>
            {
                if (this.HeaderDrag != null)
                    this.HeaderDrag.Invoke(sender, e);
            };

            this.txtUsrEnteredInfo.Text = string.Empty;
            this.AllowNullAsValue = allowNullAsValue;
            this.txtUsrEnteredInfo.TextChanged += new TextChangedEventHandler(this.OnTextChanged);
            this.txtUsrEnteredInfo.IsVisibleChanged += new DependencyPropertyChangedEventHandler(this.OnVisibleChanged);
            this.txtUsrEnteredInfo.Focus();
            this.HorizontalAlignment = HorizontalAlignment.Stretch;
        }

        /// <summary>
        /// Gets or sets the text that is displayed as the main header in this pop up.
        /// </summary>
        public string MainHeader
        {
            get
            {
                return this.txtBlkMainHeader.Text;
            }
            set
            {
                this.txtBlkMainHeader.Text = value;
            }
        }

        /// <summary>
        /// Gets or sets the text that is displayed to the user, that prompts on what is to be entered.
        /// </summary>
        public string UserPromptText
        {
            get
            {
                return this.txtBlkInfoText.Text;
            }
            set
            {
                this.txtBlkInfoText.Text = value;
                this.txtBlkInfoText.ToolTip = this.txtBlkInfoText.Text;
            }
        }

        /// <summary>
        /// Gets or sets the maximum number of characters that the user can enter.
        /// </summary>
        public int MaxLengthOfInfo
        {
            get
            {
                return this.txtUsrEnteredInfo.MaxLength;
            }
            set
            {
                this.txtUsrEnteredInfo.MaxLength = value;
            }
        }

        /// <summary>
        /// Set the default info to be shown to the user for input.
        /// </summary>
        public string CurrentInfo
        {
            get
            {
                return this.txtUsrEnteredInfo.Text;
            }

            set
            {
                this.txtUsrEnteredInfo.Text = value;
                this.txtUsrEnteredInfo.CaretIndex = this.txtUsrEnteredInfo.Text.Length;
            }
        }

        /// <summary>
        /// Gets and sets the flag specifying if the value allowed can be null or not.
        /// </summary>
        public bool AllowNullAsValue
        {
            get
            {
                return this.allowNullAsValue;
            }

            set
            {
                this.allowNullAsValue = value;
                if (allowNullAsValue)
                {
                    this.btnOk.IsEnabled = true;
                    this.btnOk.Opacity = 1.0;
                }
                else
                {
                    this.btnOk.IsEnabled = false;
                    this.btnOk.Opacity = 0.7;
                }
            }
        }

        /// <summary>
        /// Fired on visibility changed of the textbox, used to set the focus.
        /// </summary>
        /// <param name="sender">
        /// txtUsrEnteredInfo.
        /// </param>
        /// <param name="e">
        /// DependencyPropertyChangedEventArgs.
        /// </param>
        private void OnVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                this.txtUsrEnteredInfo.Focus();
            }
        }

        /// <summary>
        /// Fired on text changed of the text box. Used to determine if the OK button should be enabled or not.
        /// </summary>
        /// <param name="sender">
        /// Name text box.
        /// </param>
        /// <param name="e">
        /// Text Changed EventArgs.
        /// </param>
        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            if (!this.allowNullAsValue)
            {
                if (!string.IsNullOrEmpty(this.txtUsrEnteredInfo.Text.Trim()))
                {
                    this.btnOk.IsEnabled = true;
                    this.btnOk.Opacity = 1.0;
                }
                else
                {
                    this.btnOk.IsEnabled = false;
                    this.btnOk.Opacity = 0.7;
                }
            }
        }

        /// <summary>
        /// Fired on click of OK.
        /// </summary>
        /// <param name="sender">
        /// OK button.
        /// </param>
        /// <param name="e">
        /// RoutedEventArgs.
        /// </param>
        private void OnOkClick(object sender, RoutedEventArgs e)
        {
            if (this.InfoEntered != null)
            {
                InfoEnteredEventArgs args = new InfoEnteredEventArgs(this.txtUsrEnteredInfo.Text, false);
                this.InfoEntered.Invoke(this, args);
            }
        }

        /// <summary>
        /// Fired on click of Cancel.
        /// </summary>
        /// <param name="sender">
        /// Cancel button.
        /// </param>
        /// <param name="e">
        /// RoutedEventArgs.
        /// </param>
        private void OnCancelClick(object sender, RoutedEventArgs e)
        {
            if (this.InfoEntered != null)
            {
                InfoEnteredEventArgs args = new InfoEnteredEventArgs(this.txtUsrEnteredInfo.Text, true);                
                this.InfoEntered.Invoke(this, args);
            }
        }

        /// <summary>
        /// Handles the click of the close button.
        /// </summary>
        /// <param name="sender">
        /// Close button.
        /// </param>
        /// <param name="e">
        /// MouseButtonEventArgs.
        /// </param>
        private void OnCloseClick(object sender, MouseButtonEventArgs e)
        {
            this.OnCancelClick(this, new RoutedEventArgs());
        }
    }
}
